﻿#ifndef IMAGEVIEW_H
#define IMAGEVIEW_H
#ifdef _WIN32
#include <windows.h>
#endif

#include <QWidget>
#include <QDebug>
#include <QPoint>
#include <QPaintEvent>
#include <QPainter>
#include <QMouseEvent>
#include <QAction>

#include <thread>
#include <vector>
#include <string>

#include <opencv2/opencv.hpp>
#include "objectClass.h"
#include "Parameter.h"

enum objectType{
    DEFAULT      =-1,
    BLOCK        = 3,   //0xff0000,
    TREE         = 7,   //0x00ff00,
    WOODEN_BRIDG = 8,   //0x0000ff,
    MOUND        = 9,   //0xff00ff,
    HOLES        = 10    //0x00ffff
};

class detectObject
{
public:
    detectObject(int type_, QRect pos) : m_type(type_), m_position(pos) {}
    detectObject(int type_, int x, int y, int w, int h) : m_type(type_), m_position(QRect(x,y,w,h)) {}

    inline int getType(void) { return m_type; }
    inline QRect& getPos(void) { return m_position; }

protected:
    int           m_type;
    QRect         m_position;
};

class ImageView : public QWidget
{
    Q_OBJECT
public:
    explicit ImageView(char *fileName_, QWidget *parent = 0);
    ~ImageView() {
//        if(m_config!=NULL){
//            delete m_config;
//            m_config = NULL;
//        }
//        m_ocl.clear();
//        imageName.clear();
//        m_Rect.clear();
//        m_Object.clear();
//        printf("finished ImageView Destructor!\n");
    }

    void paintEvent(QPaintEvent *);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void keyPressEvent(QKeyEvent *event);
    void              savePoint();
    int               getTotalLine(void){ return totalLine; }
    AnoObjClass_List* getObjClass(void) {return &m_ocl;}

signals:
    void read2refresh(cv::Mat&);
    void changeWindowName(QString);
    void currentIndexChanged(int);
    void finished_exit(void);
public slots:
    void Refresh(cv::Mat &input);
    void reLoadData(void);
    void changeCurrentIndex(int index_)
    {
        savePoint();
        m_Rect.clear();
        currentIndex = index_;
        if(currentIndex==imageName.size())  {currentIndex = 0;  /*emit currentIndexChanged(0);*/}
        else if(currentIndex<0)             {currentIndex = imageName.size()-1;  /*emit currentIndexChanged(imageName.size()-1);*/}

        setImage();
    }

    void changeObjClass(QAction* act)
    {
        if(99==act->data().toInt()){
            showAll = true;
#ifdef _WIN32
            set_console_color(1);          printf("Notice: ");
            set_console_default_color();   printf("Select showAll, Any ");
            set_console_color(2);          printf("New draw");
            set_console_default_color();   printf(" and ");
            set_console_color(2);          printf(" cancel ");
            set_console_default_color();   printf("will be reserved in form of: ");
            set_console_color(FOREGROUND_GREEN); printf("%s!\n",m_ocl[currentType].name.c_str());
            set_console_default_color();
#endif
#ifdef __linux__
            printf("\033[1;31;40mNotice:\033[0m Select showAll, Any \033[1;36;40m New draw \033[0m and \033[1;36;40m cancel \033[0m will be reserved in form of: \033[1;32;40m %s!\033[0m\n",
                   m_ocl[currentType].name.c_str());
#endif
        }
        else{
            showAll = false;
            currentType = act->data().toInt();
#ifdef _WIN32
            set_console_default_color();   printf("Select :");
            set_console_color(2|8);          printf("%s!\n",m_ocl[currentType].name.c_str());
#endif
#ifdef __linux__
            printf("Select :\033[1;32;40m %s!\033[0m\n",m_ocl[currentType].name.c_str());
#endif
        }
        update();
    }

protected:
    void setImageList();
    void setImage(void);
    void loadSetting(char *fileName_);
#ifdef _WIN32
    void set_console_color(unsigned short color_index)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color_index);
    }
    void set_console_default_color(void)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
    }
#endif

public:
    int                         currentIndex;
    int                         totalLine;
protected:
    //    std::thread                *videoShow;
    cv::Mat                     curImage;
    std::vector<std::string>    imageName;
    std::string                 resultDir;
    std::string                 prefix;

    std::string                 fileName;
    bool                        needReload;
    bool                        lup,ldown;
    bool                        selected;
    bool                        showAll;
    QPoint                      lt, rb;
    QPoint                      tmpPoint;
    QImage                      QImg;
    std::vector<detectObject>   m_Rect;

    int                          currentType;
    std::vector<detectObject>    m_Object;
    AnoObjClass_List             m_ocl;
    ParameterReader              *m_config;
    int                          IMAGE_WIDTH, IMAGE_HEIGHT;
};

#endif // IMAGEVIEW_H
